//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   Field.i.hh
 * \author Jeremy Roberts
 * \date   Jul 7, 2011
 * \brief  
 * \note   Copyright (C) 2011 Jeremy Roberts. 
 */
//---------------------------------------------------------------------------//
// $Rev:: 117                                           $:Rev of last commit
// $Author:: j.alyn.roberts@gmail.com                   $:Author of last commit
// $Date:: 2011-07-08 05:27:29 +0000 (Fri, 08 Jul 2011) $:Date of last commit
//---------------------------------------------------------------------------//


#ifndef FIELD_I_HH_
#define FIELD_I_HH_

namespace slabtran
{

//---------------------------------------------------------------------------//
// CONSTRUCTORS
//---------------------------------------------------------------------------//
/*!
 * \brief Constructor.
 *
 * \param n Size of field.
 * \param v Initial value for all members of field.
 */
template<class T>
Field<T>::Field(const size_type n,
			  const T         v)
{
    d_values.resize(n, v);
}

//---------------------------------------------------------------------------//
/*!
 * \brief Copy constructor.
 */
template<class T>
Field<T>::Field(const Field &rhs)
    : d_values(rhs.d_values)
{
}

//---------------------------------------------------------------------------//
/*!
 * \brief Range constructor.
 *
 * \param b Beginning iterator to copy data from.
 * \param e Ending iterator to copy data from.
 */
template<class T>
Field<T>::Field(const_iterator b,
			  const_iterator e)
    : d_values(b, e)
{
}

//---------------------------------------------------------------------------//
/*!
 * \brief Virtual destructor.
 *
 * You need to have a virtual destructor defined; even if it is pure
 * abstract.
 */
template<class T>
Field<T>::~Field()
{
    // do nothing
}

//---------------------------------------------------------------------------//
// PUBLIC FUNCTIONS
//---------------------------------------------------------------------------//
/*!
 * \brief Assignment operator to a Field.
 *
 * Assignment is only valid if the fields have the same size.
 */
template<class T>
Field<T> &
Field<T>::operator=(const Field &rhs)
{
    if ( this == &rhs )
	return *this;

    Require(rhs.size() == size());

    d_values = rhs.d_values;

    return *this;
}

//---------------------------------------------------------------------------//
/*!
 * \brief Returns value at index \a i.
 */
template<class T>
typename Field<T>::reference
Field<T>::operator[](const size_type i)
{
    Require(valid_index(i));
    return d_values[i];
}

//---------------------------------------------------------------------------//
/*!
 * \brief Returns value at index \a i.
 */
template<class T>
typename Field<T>::const_reference
Field<T>::operator[](const size_type i) const
{
    Require(valid_index(i));
    return d_values[i];
}

//---------------------------------------------------------------------------//
/*!
 * \brief Swaps the field data with \a b.
 *
 * This Field and \a b must have the same typeid.
 */
template<class T>
void
Field<T>::swap(Field<T> &b)
{
    Require(typeid(*this) == typeid(b));
    return d_values.swap(b.d_values);
}

//---------------------------------------------------------------------------//
/*!
 * \brief Returns true if \a i is a valid index.
 */
template<class T>
bool
Field<T>::valid_index(const size_type i) const
{
    return i < d_values.size();
}


} // end namespace slabtran

#endif /* FIELD_I_HH_ */

//---------------------------------------------------------------------------//
//              end of Field.i.hh
//---------------------------------------------------------------------------//
